package com.gitee.wsl.scheduler

import com.gitee.wsl.concurrent.api.SuspendRunnable
import com.gitee.wsl.scheduler.queue.ITagTask
import com.gitee.wsl.scheduler.task.SchedulerTask
import kotlin.time.Duration

/**
 * # Scheduler
 *
 * The scheduler interface is used to run tasks in different thread pools.
 *
 * Different implementations can be used depending on the requirements of the project.
 */
 interface TaskScheduler {

    val taskRepository: TaskRepository

    val runTasksSize: Int get() =  taskRepository.runTasksSize

    val runTasks:Collection<SchedulerTask> get() = taskRepository.runTasks

    /**
     * Starts a task in the scheduler.
     *
     * @param task The task to be executed.
     * @return The task object.
     */
     fun runTask(task: SuspendRunnable): SchedulerTask

     fun queueTask(task: SuspendRunnable): ITagTask

    /**
     * Starts a task with a specified interval.
     *
     * @param delay Delay before the first task launch.
     * @param interval Interval between further task launches.
     * @param task The task to be executed.
     * @return The task object.
     */
     fun runTaskTimer(delay: Duration, interval: Duration, task: SuspendRunnable): SchedulerTask

    /**
     * Starts the execution of a task after a specified time has elapsed.
     *
     * @param delay Delay before the task execution.
     * @param task The task to be executed.
     * @return The task object.
     */
     fun runTaskLater(delay: Duration, task: SuspendRunnable): SchedulerTask

    /**
     * Shuts down the scheduler.
     *
     * Scheduler should not be used after this method is called.
     */
     fun shutdown(){
        cancelAllTasks()
     }

    /**
     * Registers a task by adding it to the tasks' map.
     *
     * @param task The task to register.
     */
    fun registerTask(task: SchedulerTask) = taskRepository.registerTask(task)


    /**
     * Unregisters a task by removing it from the tasks' map.
     *
     * @param taskId The ID of the task to unregister.
     */
    fun unregisterTask(taskId: Int) = taskRepository.unregisterTask(taskId)


    /**
     * Cancels all running tasks.
     */
    fun cancelAllTasks() = taskRepository.cancelAllTasks()


    /**
     * Generates the next unique task ID in a thread-safe manner.
     *
     * @return The next unique task ID.
     */
    fun nextId(): Int  = taskRepository.nextId()

     companion object
}

/**
 * Starts a task with a specified interval.
 *
 * @param interval Interval between further task launches.
 * @param task The task to be executed.
 * @return The task object.
 */
fun TaskScheduler.runTaskTimer(
    interval: Duration,
    task: SuspendRunnable
) = runTaskTimer(interval, interval, task)


